{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Graph Coloring\n",
    "\n",
    "The **\"Graph Coloring\"** quantum kata is a series of exercises designed\n",
    "to teach you the basics of using Grover search to solve constraint\n",
    "satisfaction problems, using graph coloring problem as an example.\n",
    "\n",
    "* You can read more about graph coloring problems [here](https://en.wikipedia.org/wiki/Graph_coloring).\n",
    "* It is strongly recommended to complete the [Grover's Algorithm kata](./../GroversAlgorithm/GroversAlgorithm.ipynb) before proceeding to this one. You can also refer to its [README.md](./../GroversAlgorithm/README.md) for the list of resources on Grover's algorithm.\n",
    "* [SolveSATWithGrover](./../SolveSATWithGrover/SolveSATWithGrover.ipynb) is another kata covering oracle implementation for solving constraint satisfaction problems.\n",
    "\n",
    "\n",
    "Each task is wrapped in one operation preceded by the description of the task.\n",
    "Your goal is to fill in the blank (marked with the `// ...` comments)\n",
    "with some Q# code that solves the task. To verify your answer, run the cell using Ctrl/⌘+Enter.\n",
    "\n",
    "Within each section, tasks are given in approximate order of increasing difficulty; \n",
    "harder ones are marked with asterisks."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To begin, first prepare this notebook for execution (if you skip this step, you'll get \"Syntax does not match any known patterns\" error when you try to execute Q# code in the next cells):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%package Microsoft.Quantum.Katas::0.10.1911.1607"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "> The package versions in the output of the cell above should always match. If you are running the Notebooks locally and the versions do not match, please install the IQ# version that matches the version of the `Microsoft.Quantum.Katas` package.\n",
    "> <details>\n",
    "> <summary><u>How to install the right IQ# version</u></summary>\n",
    "> For example, if the version of `Microsoft.Quantum.Katas` package above is 0.1.2.3, the installation steps are as follows:\n",
    ">\n",
    "> 1. Stop the kernel.\n",
    "> 2. Uninstall the existing version of IQ#:\n",
    ">        dotnet tool uninstall microsoft.quantum.iqsharp -g\n",
    "> 3. Install the matching version:\n",
    ">        dotnet tool install microsoft.quantum.iqsharp -g --version 0.1.2.3\n",
    "> 4. Reinstall the kernel:\n",
    ">        dotnet iqsharp install\n",
    "> 5. Restart the Notebook.\n",
    "> </details>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Part I. Colors Representation and Manipulation"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 1.1. Initialize register to a color\n",
    "\n",
    "**Inputs:** \n",
    "\n",
    "  1. An integer $C$ ($0 \\leq C \\leq 2^{N} - 1$).\n",
    "\n",
    "  2. An array of $N$ qubits in the $|0...0\\rangle$ state.\n",
    "\n",
    "**Goal:** \n",
    "\n",
    "Prepare the array in the basis state which represents the binary notation of $C$. \n",
    "Use little-endian encoding (i.e., the least significant bit should be stored in the first qubit).\n",
    "\n",
    "**Example:** For $N = 2$ and $C = 2$ the state should be $|01\\rangle$."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T11_InitializeColor_Test \n",
    "\n",
    "operation InitializeColor (C : Int, register : Qubit[]) : Unit is Adj {\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 1.2. Read color from a register\n",
    "\n",
    "**Input:** An array of $N$ qubits which are guaranteed to be in one of the $2^{N}$ basis states.\n",
    "\n",
    "**Output:** \n",
    "\n",
    "An $N$-bit integer that represents this basis state, in little-endian encoding. \n",
    "The operation should not change the state of the qubits.\n",
    "\n",
    "**Example:** For $N = 2$ and the qubits in the state $|01\\rangle$ return 2 (and keep the qubits in $|01\\rangle$)."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T12_MeasureColor_Test \n",
    "\n",
    "operation MeasureColor (register : Qubit[]) : Int {\n",
    "    // ...\n",
    "    return -1;\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 1.3. Read coloring from a register\n",
    "\n",
    "**Inputs:** \n",
    "\n",
    "  1. The number of elements in the coloring $K$.\n",
    "\n",
    "  2. An array of $K * N$ qubits which are guaranteed to be in one of the $2^{KN}$ basis states.\n",
    "\n",
    "**Output:** \n",
    "\n",
    "An array of $K$ $N$-bit integers that represent this basis state. \n",
    "$i$-th integer of the array is stored in qubits with indices $i * N$, $i * N + 1$, ..., $i * N + N - 1$ in little-endian format. \n",
    "The operation should not change the state of the qubits.\n",
    "\n",
    "**Example:** \n",
    "For $N = 2$, $K = 2$ and the qubits in the state $|0110\\rangle$ return `[2, 1]`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T13_MeasureColoring_Test \n",
    "\n",
    "operation MeasureColoring (K : Int, register : Qubit[]) : Int[] {\n",
    "    // ...\n",
    "    return new Int[0];\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 1.4. 2-bit color equality oracle\n",
    "\n",
    "**Inputs:** \n",
    "\n",
    "  1. An array of 2 qubits in an arbitrary state $|c_{0}\\rangle$ representing the first color.\n",
    "\n",
    "  2. An array of 2 qubits in an arbitrary state $|c_{1}\\rangle$ representing the second color.\n",
    "\n",
    "  3. A qubit in an arbitrary state $|y\\rangle$ (target qubit).\n",
    "\n",
    "**Goal:**\n",
    "\n",
    "Transform state $|c_{0}\\rangle|c_{1}\\rangle|y\\rangle$ into state $|c_{0}\\rangle|c_{1}\\rangle|y \\oplus f(c_{0},c_{1}\\rangle$ ($\\oplus$ is addition modulo 2), \n",
    "where $f(x) = 1$ if $c_{0}$ and $c_{1}$ are in the same state, and 0 otherwise. \n",
    "Leave the query register in the same state it started in.\n",
    "\n",
    "In this task you are allowed to allocate extra qubits."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T14_ColorEqualityOracle_2bit_Test \n",
    "\n",
    "operation ColorEqualityOracle_2bit (c0 : Qubit[], c1 : Qubit[], target : Qubit) : Unit is Adj+Ctl {\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 1.5. N-bit color equality oracle (no extra qubits)\n",
    "\n",
    "This task is the same as task 1.4, but in this task you are NOT allowed to allocate extra qubits."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T15_ColorEqualityOracle_Nbit_Test \n",
    "\n",
    "operation ColorEqualityOracle_Nbit (c0 : Qubit[], c1 : Qubit[], target : Qubit) : Unit is Adj+Ctl {\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Part II. Vertex coloring problem"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 2.1. Classical verification of vertex coloring\n",
    "\n",
    "**Inputs:** \n",
    "\n",
    "  1. The number of vertices in the graph $V$ ($V \\leq 6$).\n",
    "\n",
    "  2. An array of $E$ tuples of integers, representing the edges of the graph ($E \\leq 12$).  \n",
    "Each tuple gives the indices of the start and the end vertices of the edge.  \n",
    "The vertices are indexed $0$ through $V - 1$.\n",
    "\n",
    "  3. An array of $V$ integers, representing the vertex coloring of the graph. \n",
    "$i$-th element of the array is the color of the vertex number $i$.\n",
    "\n",
    "**Output:** \n",
    "\n",
    "True if the given vertex coloring is valid (i.e., no pair of vertices connected by an edge have the same color), and false otherwise.\n",
    "\n",
    "**Example:** \n",
    "\n",
    "Graph 0 -- 1 -- 2 would have $V = 3$ and `edges = [(0, 1), (1, 2)]`.  \n",
    "Some of the valid colorings for it would be `[0, 1, 0]` and `[-1, 5, 18]`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T21_IsVertexColoringValid_Test \n",
    "\n",
    "function IsVertexColoringValid (V : Int, edges: (Int, Int)[], colors: Int[]) : Bool {\n",
    "    // ...\n",
    "    return true;\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 2.2. Oracle for verifying vertex coloring\n",
    "\n",
    "**Inputs:**\n",
    "\n",
    "  1. The number of vertices in the graph $V$ ($V \\leq 6$).\n",
    "\n",
    "  2. An array of $E$ tuples of integers, representing the edges of the graph (E $\\leq$ 12).  \n",
    "Each tuple gives the indices of the start and the end vertices of the edge.  \n",
    "The vertices are indexed $0$ through $V - 1$.\n",
    "\n",
    "  3. An array of $2V$ qubits `colorsRegister` that encodes the color assignments.\n",
    "\n",
    "  4. A qubit in an arbitrary state $|y\\rangle$ (target qubit).\n",
    "\n",
    "**Goal:**\n",
    "\n",
    "Transform state $|x, y\\rangle$ into state $|x, y \\oplus f(x)\\rangle$  ($\\oplus$ is addition modulo 2), \n",
    "where $f(x) = 1$ if if the given vertex coloring is valid, and 0 otherwise. \n",
    "Leave the query register in the same state it started in.\n",
    "\n",
    "Each color in `colorsRegister` is represented as a 2-bit integer in little-endian format. \n",
    "See task 1.3 for a more detailed description of color assignments."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T22_VertexColoringOracle_Test \n",
    "\n",
    "operation VertexColoringOracle (V : Int, \n",
    "                                edges : (Int, Int)[], \n",
    "                                colorsRegister : Qubit[], \n",
    "                                target : Qubit) : Unit is Adj+Ctl {\n",
    "    // ...\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Task 2.3. Using Grover's search to find vertex coloring\n",
    "\n",
    "**Inputs:** \n",
    "\n",
    "  1. The number of vertices in the graph $V$ ($V \\leq 6$).\n",
    "\n",
    "  2. A marking oracle which implements vertex coloring verification, as implemented in task 2.2.\n",
    "\n",
    "**Output:** \n",
    "\n",
    "A valid vertex coloring for the graph, in a format used in task 2.1."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%kata T23_GroversAlgorithm_Test \n",
    "\n",
    "operation GroversAlgorithm (V : Int, oracle : ((Qubit[], Qubit) => Unit is Adj)) : Int[] {\n",
    "    // ...\n",
    "    return new Int[V];\n",
    "}"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Q#",
   "language": "qsharp",
   "name": "iqsharp"
  },
  "language_info": {
   "file_extension": ".qs",
   "mimetype": "text/x-qsharp",
   "name": "qsharp",
   "version": "0.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
